In [1]:
import sys
sys.path.append(r'AutomaticDifferentiation\build\Release')
import automatic_differentiation as ad
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from IPython.display import HTML
In [2]:
def display_function_and_derivative(func, x_start, x_end):
# Create the figure and axis
fig, ax = plt.subplots(figsize=(10, 6))
plt.close() # Prevents displaying the static figure
# Set the x range for our function
x_range = np.linspace(x_start, x_end, 100)
# Calculate function values for the full curve
y_values = np.array([func(x).get_x() for x in x_range])
# Plot the main function curve
ax.plot(x_range, y_values, 'b-', lw=2, label='f(x)')
# Point that will move along the curve
point, = ax.plot([], [], 'ro', ms=5)
# Tangent line that will update
tangent_line, = ax.plot([], [], 'r-', lw=1, label='Tangent')
# Text to display the derivative value
derivative_text = ax.text(0.02, 0.95, '', transform=ax.transAxes)
# Set up the axes
ax.set_xlim(x_start, x_end)
ylim_margin = (max(y_values) - min(y_values)) / 20
ax.set_ylim(min(y_values) - ylim_margin, max(y_values) + ylim_margin)
ax.set_xlabel('x', fontsize=14)
ax.set_ylabel('f(x)', fontsize=14)
ax.set_title('Function and its Derivative', fontsize=16)
ax.grid(True)
ax.legend(loc='lower right')
# Number of frames in the animation
frames = 100
# Points along the curve to evaluate
animation_x_values = np.linspace(x_start, x_end, frames)
# Update function for the animation
def update(frame):
# Current x value
x = animation_x_values[frame]
# Get function value and derivative
dual_number = func(x)
f_x = dual_number.get_x()
df_x = dual_number.get_dx()
# Update the point position
point.set_data([x], [f_x])
# Create tangent line
# The tangent line is represented by: y = f'(x)*(x-x0) + f(x0)
tangent_x = np.array([x_start, x_end])
tangent_y = df_x * (tangent_x - x) + f_x
tangent_line.set_data(tangent_x, tangent_y)
# Update derivative text
derivative_text.set_text(f"f'(x) = {df_x:.3f}")
return point, tangent_line, derivative_text
# Create the animation
animation = FuncAnimation(fig, update, frames=frames, interval=50, blit=True)
return animation
In [3]:
def polynomial(x):
dn = ad.DualNumber(x, 1)
return dn ** 3 + 50 * dn ** 2 - 3 * dn + 18
HTML(display_function_and_derivative(polynomial, -80, 60).to_jshtml())
Out[3]:
In [4]:
def polynomial(x):
dn = ad.DualNumber(x, 1)
return dn ** 2 - 5 * dn + 6 - 5 * dn ** 3 - 5 * np.e ** (-50 * dn ** 2)
HTML(display_function_and_derivative(polynomial, -0.5, 0.5).to_jshtml())
Out[4]:
In [5]:
def polynomial(x):
dn = ad.DualNumber(x, 1)
return np.e ** (-0.1 * dn) * (dn * 5).sin()
HTML(display_function_and_derivative(polynomial, 0, 4).to_jshtml())
Out[5]:
In [6]:
def polynomial(x):
dn = ad.DualNumber(x, 1)
return (dn.sin()).tan() - (3 * dn).cos()
HTML(display_function_and_derivative(polynomial, -3, 5).to_jshtml())
Out[6]: